// Copyright (C) Kumo inc. and its affiliates.
// Author: Jeff.li lijippy@163.com
// All rights reserved.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
//


#include <cantor/common/expr_class.h>
#include <vector>
#include <turbo/strings/str_format.h>
#include <turbo/strings/str_join.h>
#include <turbo/strings/internal/str_format/extension.h>

namespace cantor::pb::ast {
    static cantor::pb::ast::ExprNodeClass expr_classes[] = {
        ENC_NONE,
        ENC_CLAUSE,
        ENC_DDL,
        ENC_DQL,
        ENC_DCL,
        ENC_DML,
        ENC_DISPATCH,
        ENC_DEFINITE,
        ENC_FUNC,
        ENC_CTOR,
        ENC_SUBQUERY,
        ENC_INDIRECTION
    };

    static std::string_view expr_classes_str[] = {
        "ENC_NONE",
        "ENC_CLAUSE",
        "ENC_DDL",
        "ENC_DQL",
        "ENC_DCL",
        "ENC_DML",
        "ENC_DISPATCH",
        "ENC_DEFINITE",
        "ENC_FUNC",
        "ENC_CTOR",
        "ENC_SUBQUERY",
        "ENC_INDIRECTION"
    };


    std::vector<cantor::pb::ast::ExprNodeClass> expr_class_dispatch(cantor::pb::ast::ExprNodeClass a) {
        std::vector<cantor::pb::ast::ExprNodeClass> result;
        auto len  = TURBO_ARRAYSIZE(expr_classes);
        for (auto i = 0; i < len; i++) {
            if (expr_classes[i] & a) {
                result.emplace_back(expr_classes[i]);
            }
        }
        return result;
    }

    std::vector<std::string_view> expr_class_dispatch_string(cantor::pb::ast::ExprNodeClass a) {
        std::vector<std::string_view> result;
        auto len  = TURBO_ARRAYSIZE(expr_classes);
        for (size_t i = 0; i < len; ++i) {
            if (expr_classes[i] & a) {
                result.emplace_back(expr_classes_str[i]);
            }
        }
        return result;
    }

    std::string expr_class_to_string(cantor::pb::ast::ExprNodeClass expr_class, const std::string &spliter) {
        auto dispatch = expr_class_dispatch_string(expr_class);
        auto result = turbo::str_join(dispatch, spliter);
        return result;
    }
} // namespace cantor::pb::ast
